/**
 * Copyright (c) 2008, Keisuke Inoue, Syracuse Unviersity
 * All rights reserved.
 *
 */
package edu.syr.iis.web.controller;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import edu.syr.iis.web.model.Adjacency;
import edu.syr.iis.web.model.AdjacencyManager;
import edu.syr.iis.web.model.DialogueAct;
import edu.syr.iis.web.model.DialogueActLabel;
import edu.syr.iis.web.model.DialogueActLabelManager;
import edu.syr.iis.web.model.DialogueActManager;
import edu.syr.iis.web.model.DialogueActScheme;
import edu.syr.iis.web.model.DialogueActSchemeManager;
import edu.syr.iis.web.model.Message;
import edu.syr.iis.web.model.MessageManager;
import edu.syr.iis.web.model.User;
import edu.syr.iis.web.util.Key;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

/**
 * @author kinoue
 *
 */
public class AnnotateMessageController  extends SimpleFormController 
{
	private static Log log = LogFactory.getLog(AnnotateMessageController.class);

	/*
	 * Managers
	 */
	MessageManager messageManager;
	AdjacencyManager adjacencyManager;
	DialogueActManager dialogueActManager;
	DialogueActLabelManager dialogueActLabelManager;
	DialogueActSchemeManager dialogueActSchemeManager;	

	/*
	 * Model Object
	 */
	Message message = null;

	/*
	 * Reference Data
	 */
	List <DialogueActLabel> dalabels = null;
	List <DialogueActScheme> daschemes = null;

	Message nextMessage = null;
	Message previousMessage = null;

	List <Message> sameMessages = null;

	int copyMessageId;
	Message copyMessage;

	@Override
	protected Object formBackingObject(HttpServletRequest request)
	throws Exception
	{
		log.debug("Entered formBackingObject.");

		if (request.getParameter(Key.MSG_ID) != null
				&& request.getParameter(Key.MSG_ID).trim().length() > 0) 
		{
			int messageId = Integer.parseInt(request.getParameter(Key.MSG_ID));
			message = messageManager.getMessage(messageId, false);			
		} else 
		{
			throw new Exception(Key.MSG_ID + " was not specifed.");
		}	

		/*
		if (request.getParameter(Key.COPY_MSG_ID) != null
				&& request.getParameter(Key.COPY_MSG_ID).trim().length() > 0) 
		{
			copyMessageId = Integer.parseInt(request.getParameter(Key.COPY_MSG_ID));
			copyMessage = messageManager.getMessage(copyMessageId);
			message.setDialogueActLabels(new HashSet<DialogueActLabel>(copyMessage.getDialogueActLabels()));

			System.out.println("Copied lables from the message: " + copyMessage.getMessageId());
		} 
		 */
		
		if (request.getParameter(Key.DEL_DA_ID) != null
				&& request.getParameter(Key.DEL_DA_ID).trim().length() > 0) 
		{
			int daId = Integer.parseInt(request.getParameter(Key.DEL_DA_ID));   
			DialogueAct da = dialogueActManager.getDialogueAct(daId);
			if (da != null) {
				System.out.println("Deleting: " + da.toString());			
				message.deleteDialogueAct(daId);
				dialogueActManager.deleteDialogueAct(da);
			}
		}	
				
		messageManager.saveMessage(message);
		return message;
	}

	@Override
	protected Map<String, Object> referenceData(HttpServletRequest request, Object obj, Errors errors) throws Exception
	{  
		HashMap<String, Object> model = new HashMap<String, Object>();
	
		try {
		
		Message message = (Message) obj;
		
		Set<User> annotators = message.getConversation().getAnnotators();
			
		previousMessage = messageManager.getPreviousMessage(message);
		nextMessage = messageManager.getNextMessage(message);

		model.put(Key.NEXT_MSG, nextMessage);
		model.put(Key.PREV_MSG, previousMessage);

		dalabels = dialogueActLabelManager.getDialogueActLabels();
		model.put(Key.DA_LABELS, dalabels);

		model.put(Key.ADJACENCIES, adjacencyManager.getAdjacencies());
		model.put(Key.DA_FUNCTIONS, dialogueActLabelManager.getDialogueActLabelsBySchemeAndDimension("Inoue", "Function"));
		model.put(Key.DA_DOMAINS, dialogueActLabelManager.getDialogueActLabelsBySchemeAndDimension("Inoue", "Domain"));
		
		model.put(Key.USERS, annotators);
		
		} catch (Exception e) {
		   System.out.println("Error: " + e);
		}
		return model;
	}    

	@Override
	protected void initBinder(
			HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception
			{
		// binder.registerCustomEditor(DialogueActLabel.class, new DialogueActLabelPropertyEditor());

		binder.registerCustomEditor(Adjacency.class, new AdjacencyPropertyEditor(adjacencyManager));
		binder.registerCustomEditor(DialogueActLabel.class, new DialogueActLabelPropertyEditor(dialogueActLabelManager));
		binder.registerCustomEditor(DialogueAct.class, new DialogueActPropertyEditor(dialogueActManager));
		
		binder.registerCustomEditor(Collection.class, Key.DA_LABELS, new CustomCollectionEditor(Collection.class) {
			@Override
			protected Object convertElement(Object element) {
				if (element != null) {
					int id = Integer.parseInt((String)element);
					DialogueActLabel dalabel = dialogueActLabelManager.getDialogueActLabel(id);
					return dalabel;
				}
				return null;
			}
		});

			}


	@Override
	protected ModelAndView onSubmit(
			HttpServletRequest request,
			HttpServletResponse response,
			Object command,
			BindException errors)
	{
		Message message = (Message) command;

		messageManager.saveMessage(message);

		/*
	if (labelSame) {
	    System.out.println("Changing all the same message's labels!");

	    for (Message m: sameMessages){
		HashSet <DialogueActLabel> daset = new HashSet<DialogueActLabel>(m.getDialogueActLabels());
		daset.addAll(message.getDialogueActLabels());
		m.setDialogueActLabels(daset);
		messageManager.saveMessage(message);	
	    }
	}
		 */
		System.out.println("onSubmit is called with message ID: " + message.getMessageId());
		
		return new ModelAndView(getSuccessView() + "?messageId=" + nextMessage.getMessageId());
	}


	public void setMessageManager(MessageManager messageManager)
	{
		this.messageManager = messageManager;
	}

	public void setDialogueActLabelManager(
			DialogueActLabelManager dialogueActLabelManager)
	{
		this.dialogueActLabelManager = dialogueActLabelManager;
	}

	public void setDialogueActSchemeManager(
			DialogueActSchemeManager dialogueActSchemeManager)
	{
		this.dialogueActSchemeManager = dialogueActSchemeManager;
	}
	
	public void setAdjacencyManager(AdjacencyManager adjacencyManager) {
		this.adjacencyManager = adjacencyManager;
	}


	public void setDialogueActManager(DialogueActManager dialogueActManager)
	{
		this.dialogueActManager = dialogueActManager;
	}




}
